package com.tongtech.space.common.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.Data;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import lombok.extern.slf4j.Slf4j;


/**
 * TIS 请求工具类 2.0
 * Todo 待优化
 *
 * @author jinjiayu
 * @since 2021/1/14
 */
@Slf4j
@Component
public class TisRequest {
	private static PoolingHttpClientConnectionManager POOLING_HTTP_CLIENT_CONNECTION_MANAGER = null;
	private static final HttpClient HTTP_CLIENT;
	private static final String TIS_URL_VERSION = "v1.0";
	private static TisToken tisToken = null;

	static {
		Protocol.registerProtocol("https",
				new Protocol("https", (ProtocolSocketFactory)new MySecureProtocolSocketFactory(), 443));
		MultiThreadedHttpConnectionManager connectionManager =
				new MultiThreadedHttpConnectionManager();
		HTTP_CLIENT = new HttpClient(connectionManager);

		// 采用绕过验证的方式处理https请求
		try {
			SSLContext sslcontext = createIgnoreVerifySSL();
			// 设置协议http和https对应的处理socket链接工厂的对象
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
					.register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)).build();

			POOLING_HTTP_CLIENT_CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			POOLING_HTTP_CLIENT_CONNECTION_MANAGER.setMaxTotal(500);
			POOLING_HTTP_CLIENT_CONNECTION_MANAGER.setDefaultMaxPerRoute(500);
		} catch (KeyManagementException | NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	// ==============================================1.TIS-查询===================================================
	/**
	 * 1. 查询-根据java bean查询单条泛型业务数据
	 *
	 * @param metaId
	 * @param param
	 * @param typeReference
	 * @return <E>
	 * @author jinjiayu
	 */
	public <E> E queryDataSingleAsGeneric(String metaId, Object param, TypeReference<E> typeReference) {
		JSONArray jsonArray = queryDataListAsJSONArray(metaId, param);
		return jsonArray == null ? null : jsonArray.getJSONObject(0).toJavaObject(typeReference);
	}

	/**
	 * 2. 查询-根据java bean查询多条泛型业务数据
	 *
	 * @param metaId
	 * @param param
	 * @param typeReference
	 * @return <E>
	 * @author jinjiayu
	 */
	public <E> List<E> queryDataListAsGeneric(String metaId, Object param, TypeReference<E> typeReference) {
		JSONArray jsonArray = queryDataListAsJSONArray(metaId, param);
		return jsonArray == null ? null : jsonArray.toJavaObject(typeReference);
	}

	/**
	 * 3. 查询-根据java bean查询单条JSONObject业务数据
	 *
	 * @param metaId
	 * @param param
	 * @return JSONObject
	 * @author jinjiayu
	 */
	public JSONObject queryDataSingleAsJSONObject(String metaId, Object param) {
		JSONArray jsonArray = queryDataListAsJSONArray(metaId, param);
		return jsonArray == null ? null : jsonArray.getJSONObject(0);
	}

	/**
	 * 4. 查询-根据java bean查询多条JSONArray业务数据
	 *
	 * @param metaId
	 * @param param
	 * @return JSONArray
	 * @author jinjiayu
	 */
	public JSONArray queryDataListAsJSONArray(String metaId, Object param) {
		String result = queryByJSONObject(metaId, (JSONObject) JSON.toJSON(param));
		return JSON.parseObject(result).getJSONObject("response").getJSONArray("results");
	}

	/**
	 * 5. 查询-根据java bean查询完整JSONObject格式数据
	 *
	 * @param metaId
	 * @param param
	 * @return JSONObject
	 * @author jinjiayu
	 */
	public JSONObject queryAsJSONObject(String metaId, Object param) {
		String result = queryByJSONObject(metaId, (JSONObject) JSON.toJSON(param));
		return JSON.parseObject(result);
	}



	// ============================================2.TIS-新增=====================================================
	/**
	 * 1.新增单个
	 *
	 * @param metaId
	 * @param object
	 * @return boolean
	 * @author jinjiayu
	 */
	public boolean addSingleData(String metaId, Object object) {
		return add(metaId, (JSONObject) JSON.toJSON(object));
	}

	/**
	 * 2.新增多个
	 *
	 * @param metaId
	 * @param list
	 * @return boolean
	 * @author jinjiayu
	 */
	public <E> boolean addList(String metaId, List<E> list) {
		JSONArray jsonArray = (JSONArray) JSON.toJSON(list);
		if (jsonArray == null || jsonArray.size() <= 0) {
			return false;
		}

		for (int i = 0; i < jsonArray.size(); i++) {
			add(metaId, jsonArray.getJSONObject(i));
		}

		return true;
	}



	// ==================================3.TIS-更新=======================================
	/**
	 * 1. 更新单条
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	public boolean updateSingle(String metaId, String hql, Object data) {
		return update(metaId, hql, (JSONObject) JSON.toJSON(data));
	}

	/**
	 * 2. 更新多条
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	public <E> boolean updateList(String metaId, String hql, List<E> list) {
		JSONArray jsonArray = (JSONArray) JSON.toJSON(list);
		if (jsonArray == null || jsonArray.size() <= 0) {
			return false;
		}

		for (int i = 0; i < jsonArray.size(); i++) {
			update(metaId, hql, jsonArray.getJSONObject(i));
		}

		return true;
	}



	// ==============================================4.TIS-删除==================================================
	/**
	 * 1. 删除单条
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	public boolean deleteSingle(String metaId, String hql, Object data) {
		return delete(metaId, hql, (JSONObject) JSON.toJSON(data));
	}

	/**
	 * 2. 删除多条
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	public <E> boolean deleteList(String metaId, String hql, List<E> list) {
		JSONArray jsonArray = (JSONArray) JSON.toJSON(list);
		if (jsonArray == null || jsonArray.size() <= 0) {
			return false;
		}

		for (int i = 0; i < jsonArray.size(); i++) {
			delete(metaId, hql, jsonArray.getJSONObject(i));
		}

		return true;
	}



	// ==============================================5.TIS-文件上传下载-删除==================================================
	/**
	 * tis文件上传
	 * @param file
	 * @param filedName
	 * @param params
	 * @return String
	 */
	public String doUploadfile( File file,String filedName,Map<String,String> params) {
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(POOLING_HTTP_CLIENT_CONNECTION_MANAGER).build();
		CloseableHttpResponse httpResponse = null;
		try {
			String url=getTisUploadfile();
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("Authorization", "Bearer "+getTisToken().getValue());
			FileBody binFileBody = new FileBody(file);
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            // add the file params
            multipartEntityBuilder.addPart(filedName, binFileBody);
            // 设置上传的其他参数
            if (params != null && params.size() > 0) {
                Set<String> keys = params.keySet();
                for (String key : keys) {
                    multipartEntityBuilder.addPart(key, new StringBody(params.get(key), ContentType.TEXT_PLAIN));
                }
            }
            // 发出HTTP request
            HttpEntity entity = multipartEntityBuilder.build();
            httpPost.setEntity(entity);
            httpResponse = httpClient.execute(httpPost);

            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 取出回应字串
//                logger.debug("ZGH2"+EntityUtils.toString((httpResponse.getEntity()),HTTP.UTF_8));
                return EntityUtils.toString(httpResponse.getEntity(),HTTP.UTF_8);
            } else {
                return "false";
            }
			
		}catch(IOException e) {
			e.printStackTrace();
			return "false";
		}finally {
			try {
				if (httpResponse != null) {
					EntityUtils.consume(httpResponse.getEntity());
					httpResponse.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
    }

	
	/**
	 * tis下载方法
	 * @param fileId
	 * @param filename
	 * @param request
	 * @param response
	 */
	public void doDownLoad(String fileId,String filename,HttpServletRequest request,HttpServletResponse response) {
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(POOLING_HTTP_CLIENT_CONNECTION_MANAGER).build();
		CloseableHttpResponse httpResponse = null;
		OutputStream out = null;
        InputStream in = null;
		try {
			String url=getTisDownloadfile()+ "?fileId=" + fileId;
			HttpGet get = new HttpGet(url);
			get.setHeader("Authorization", "Bearer " + getTisToken().getValue());
			httpResponse = httpClient.execute(get);
			HttpEntity entity = httpResponse.getEntity();
			in = entity.getContent();
			
			response.setContentType(request.getServletContext().getMimeType(filename));
			// 设置Content-Disposition
			response.setHeader("Content-Disposition", "attachment;filename=" + filename);
			if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
				filename = URLEncoder.encode(filename, "UTF-8");
			} else {
				filename = new String(filename.getBytes("UTF-8"), "ISO8859-1");
			}
			try {
				response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", filename));
//				response.setContentType("application/vnd.ms-excel;charset=utf-8");
				response.setContentType("multipart/form-data");
				response.setCharacterEncoding("UTF-8");
				out = response.getOutputStream();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 写文件
			int b;
			while ((b = in.read()) != -1) {
				out.write(b);
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if (in != null) {
					in.close();
				}
				if (out != null) {
					out.close();
				}
				if (httpResponse != null) {
					EntityUtils.consume(httpResponse.getEntity());
					httpResponse.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}



	/**
	 * tis文件删除上传
	 * @param fileId
	 * @param data
	 * @return   success 成功   false 失败
	 */
	public  String doDeleteFile(String fileId,String data) {
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(POOLING_HTTP_CLIENT_CONNECTION_MANAGER).build();
		CloseableHttpResponse httpResponse = null;
		try {
			String url=getTisDeletefile()+ "?fileId=" + fileId;
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("Authorization", String.join(" ", "Bearer", getTisToken().getValue()));
		    httpPost.setHeader("TIS-Update-Api-Context", "true");
		    // 发出HTTP request
            //logger.debug("ZGH4" + data);
            StringEntity entity = new StringEntity(data, HTTP.UTF_8);
             //logger.debug("ZGH5"+entity);
            entity.setContentEncoding(HTTP.UTF_8);
            // logger.debug("ZGH1"+entity);
            httpPost.setEntity(entity);

            httpResponse = httpClient.execute(httpPost);
            // 取得HTTP response
            // 若状态码为200 ok
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 取出回应字串
//                logger.debug("删除成功" + EntityUtils.toString((httpResponse.getEntity()), HTTP.UTF_8));
                return "success";
            } else {
//                logger.debug("post失败,url为："+url);
//                logger.debug("post失败,data为："+data);
//                logger.debug("删除失败"+EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8));
//                logger.debug("doPost Error Response: " + httpResponse.getStatusLine().toString());
                return "false";
            }

		}catch(IOException e) {
			e.printStackTrace();
			return "false";
		}finally {
			try {
				if (httpResponse != null) {
					EntityUtils.consume(httpResponse.getEntity());
					httpResponse.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
    }


	// ==============================================私有方法,请勿放置任何业务方法==========================================
	/**
	 * Tis 查询
	 *
	 * @param metaId data
	 * @return String
	 * @author jinjiayu
	 */
	private String queryByJSONObject(String metaId, JSONObject data) {
		JSONObject node = new JSONObject();
		node.put("metaId", metaId);
		// 设置分页参数,默认0-9999
		node.put("limit", (data.isEmpty() || data.getInteger("limit") == null) ? 9999 : data.getInteger("limit"));
		node.put("offset", (data.isEmpty() || data.getInteger("offset") == null) ? 0 : data.getInteger("offset"));
		// 设置查询条件
		node.put("data", data);

		return requestTis(getTisToken(), getTisQueryUrl(), node);
	}

	/**
	 * Tis 新增 (根据 metaId, JSONObject)
	 *
	 * @param metaId data
	 * @return boolean
	 * @author jinjiayu
	 */
	private boolean add(String metaId, JSONObject data) {
		JSONObject node = new JSONObject();
		node.put("metaId", metaId);
		node.put("data", data);

		String tisAddUrl = getTisAddUrl();
		log.info("TIS 新增数据:" + node.toString());
		String result = requestTis(getTisToken(), tisAddUrl, node);
		if (StringUtils.isNotBlank(result)) {
			log.info("新增" + metaId + "数据成功！");
			return true;
		}
		log.error("新增" + metaId + "数据失败！");
		return false;
	}

	/**
	 * Tis 更新 (根据JSONObject)
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	private boolean update(String metaId, String hql, JSONObject data) {
		JSONObject node = new JSONObject();
		node.put("metaId", metaId);
		node.put("statement", hql);
		// 设置删除条件
		node.put("data", data);
		String updateUrl = getTisUpdateUrl();
		log.info("更新TIS库 node 数据:" + node.toString());
		String result = requestTis(getTisToken(), updateUrl, node);
		if (StringUtils.isNotBlank(result)) {
			log.info("更新" + metaId + "旧数据成功！");
			return true;
		}
		log.error("更新" + metaId + "旧数据失败！");
		return false;
	}

	/**
	 * Tis 删除 (根据JSONObject)
	 *
	 * @param metaId hql data
	 * @return boolean
	 * @author jinjiayu
	 */
	private boolean delete(String metaId, String hql, JSONObject data) {
		JSONObject node = new JSONObject();
		node.put("metaId", metaId);
		node.put("statement", hql);
		// 设置删除条件
		node.put("data", data);

		String deleteUrl = getTisDeleteUrl();
		log.info("删除TIS库 node 数据:" + node.toString());
		String result = requestTis(getTisToken(), deleteUrl, node);
		if (StringUtils.isNotBlank(result)) {
			log.info("删除" + metaId + "旧数据成功！");
			return true;
		}
		log.error("删除" + metaId + "旧数据失败！");
		return false;
	}

	/**
	 * 请求TIS
	 *
	 * @param tisToken url node
	 * @return String
	 * @author jinjiayu
	 */
	private String requestTis(TisToken tisToken, String url, JSONObject node) {
		Map<String, Object> header = new HashMap<>();
		header.put("Authorization", "Bearer " + tisToken.getValue());
		header.put("Content-Type", "application/json;charset=utf-8");
		header.put("SessionIndex", "");
		String ret ="";
		try {
			ret = post(url, node, header);
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		return ret;
	}

	/**
	 * 获取TIS token
	 *
	 * @return DefaultOAuth2AccessToken
	 * @author jinjiayu
	 */
	private static TisToken getTisToken() {
		if (tisToken != null && !tisToken.isExpired()) {
			return tisToken;
		}
		Calendar calendar = Calendar.getInstance();

		String url = getTisTokenUrl();
		PostMethod post = new PostMethod(url);
		post.setRequestHeader(
				new org.apache.commons.httpclient.Header("Content-Type", "application/x-www-form-urlencoded"));

		String token = null;
		try {
			HTTP_CLIENT.executeMethod(post);
			token = post.getResponseBodyAsString();
		} catch (Exception e) {
			log.info("Tis 请求失败,错误原因是: " + e.getMessage());
		} finally {
			post.releaseConnection();
		}

		log.info("token is " + token);
		JSONObject object = JSON.parseObject(token);

		tisToken = new TisToken(object.getString("access_token"));
		Set<String> scope = new HashSet<>();
		scope.add(object.getString("scope"));
		tisToken.setScope(scope);
		calendar.add(Calendar.SECOND, object.getInteger("expires_in"));
		tisToken.setExpiration(calendar.getTime());

		return tisToken;
	}

	/**
	 * Tis 请求
	 *
	 * @param url jsonObject header
	 * @return String
	 * @author jinjiayu
	 */
	private String post(String url, JSONObject jsonObject, Map<String,Object> header) {
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(POOLING_HTTP_CLIENT_CONNECTION_MANAGER).build();
		CloseableHttpResponse httpResponse = null;
		try {

			HttpPost post = new HttpPost(url);
			RequestConfig config = RequestConfig.custom().setConnectTimeout(5000)
					.setConnectionRequestTimeout(500)
					.setSocketTimeout(5000)
					.setStaleConnectionCheckEnabled(true)
					.build();
			post.setConfig(config);
			StringEntity entity = new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON);
			post.setEntity(entity);
			if (null != header) {
				for (Map.Entry<String, Object> param : header.entrySet()) {
					post.setHeader(param.getKey(), (String) param.getValue());
				}
			}
			httpResponse = httpClient.execute(post);
			String responseBody = "";
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				responseBody = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
			} else {
				log.info("TIS httpResponse----" + EntityUtils.toString(httpResponse.getEntity(), "UTF-8"));
			}
			return responseBody;
		}catch(IOException e) {
			log.error(e.getMessage());
			return "";
		}finally {
			try {
				if (httpResponse != null) {
					EntityUtils.consume(httpResponse.getEntity());
					httpResponse.close();
				}
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}

	/**
	 * 绕过验证
	 *
	 * @return SSLContext
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 */
	private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
		SSLContext sc = SSLContext.getInstance("SSL");

		// 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
		X509TrustManager trustManager = new X509TrustManager() {
			@Override
			public void checkClientTrusted(
					java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
					String paramString) throws CertificateException {
			}

			@Override
			public void checkServerTrusted(
					java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
					String paramString) throws CertificateException {
			}

			@Override
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};

		sc.init(null, new TrustManager[] { trustManager }, null);
		return sc;
	}






	// ==========================================私有方法-TIS URL配置==================================================
	private static String get(String name) {
		return PropertyUtil.getProperty(name);
	}

	private static String getAmBaseUrl() {
		return get("api.gateway.ip") + ":" + get("api.gateway.port");
	}

	private static String getTisTokenUrl() {
		return get("api.manager.token.ip") + ":" + get("api.manager.token.port")
				+ "/oauth2/token?grant_type=client_credentials&client_id=" + get("client.key") + "&client_secret="
				+ get("client.secret");
	}

	/**
	 * TIS模型查询
	 *
	 * @return String
	 * @author jinjiayu
	 */
	private static String getTisQueryUrl() {
		return getAmBaseUrl() + "/resource_access_orm/data/query/" + TIS_URL_VERSION;
	}

	/**
	 * TIS模型增加
	 *
	 * @return String
	 * @author jinjiayu
	 */
	private static String getTisAddUrl() {
		return getAmBaseUrl() + "/resource_access_orm/data/create/" + TIS_URL_VERSION;
	}

	/**
	 * TIS模型数据更新
	 *
	 * @return String
	 * @author jinjiayu
	 */
	private static String getTisUpdateUrl() {
		return getAmBaseUrl() + "/resource_access_orm/data/update/" + TIS_URL_VERSION;
	}

	/**
	 * TIS模型数据删除
	 *
	 * @return String
	 * @author jinjiayu
	 */
	private static String getTisDeleteUrl() {
		return getAmBaseUrl() + "/resource_access_orm/data/delete/" + TIS_URL_VERSION;
	}

	/**
	 *  TIS下载文件
	 * @return
	 */

	public static String getTisDownloadfile() {
		return getAmBaseUrl() + "/fsc_download/" + TIS_URL_VERSION;
	}
	
	/**
	 *  TIS上传文件
	 * @return
	 */
	public static String getTisUploadfile() {
		return getAmBaseUrl() + "/fsc_upload/" + TIS_URL_VERSION;
	}
	/**
	 *  删除文件
	 * @return
	 */
	public static String getTisDeletefile() {
		return getAmBaseUrl() + "/fsc_delete/" + TIS_URL_VERSION;
	}



	// =================================================静态内部类=====================================================

	/**
	 * 自定义tis token类
	 *
	 * @author jinjiayu
	 * @since 2021/1/14
	 */
	@Data
	private static class TisToken {
		private String value;
		private Date expiration;
		private String tokenType;
		private Set<String> scope;
		private Map<String, Object> additionalInformation;

		public TisToken(String value) {
			this.tokenType = "Bearer".toLowerCase();
			this.additionalInformation = Collections.emptyMap();
			this.value = value;
		}

		public boolean isExpired() {
			return this.expiration != null && this.expiration.before(new Date());
		}
	}

	public static class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {

		private SSLContext sslcontext = null;

		private static SSLContext createSSLContext() {
			try {
				SSLContext context = SSLContext.getInstance("SSL");
				context.init(
						null,
						new TrustManager[]{new MyX509TrustManager()},
						null);
				return context;
			} catch (Exception e) {
				throw new HttpClientError(e.toString());
			}
		}

		private SSLContext getSSLContext() {
			if (this.sslcontext == null) {
				this.sslcontext = createSSLContext();
			}
			return this.sslcontext;
		}

		@Override
		public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
			return getSSLContext().getSocketFactory().createSocket(
					socket,
					host,
					port,
					autoClose
			);
		}

		@Override
		public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException {
			return getSSLContext().getSocketFactory().createSocket(
					host,
					port,
					localAddress,
					localPort);
		}

		@Override
		public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, org.apache.commons.httpclient.params.HttpConnectionParams params) throws IOException {
			if (params == null) {
				throw new IllegalArgumentException("Parameters may not be null");
			}
			int timeout = params.getConnectionTimeout();
			SocketFactory socketfactory = getSSLContext().getSocketFactory();
			if (timeout == 0) {
				return socketfactory.createSocket(host, port, localAddress, localPort);
			} else {
				Socket socket = socketfactory.createSocket();
				SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
				SocketAddress remoteaddr = new InetSocketAddress(host, port);
				socket.bind(localaddr);
				socket.connect(remoteaddr, timeout);
				return socket;
			}
		}

		@Override
		public Socket createSocket(String host, int port) throws IOException {
			return getSSLContext().getSocketFactory().createSocket(
					host,
					port);
		}
	}

	public static class MyX509TrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

		}

		@Override
		public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[]{};
		}

	}

	public  String uploadTis(String path,RestTemplate restTemplate){
		String url=getTisUploadfile();

		//设置请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("multipart/form-data");
		headers.setContentType(type);
		headers.set("Authorization", "Bearer "+getTisToken().getValue());

		//设置请求体，注意是LinkedMultiValueMap
		FileSystemResource fileSystemResource = new FileSystemResource(path);
		MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
		form.add("file", fileSystemResource);

		//用HttpEntity封装整个请求报文
		org.springframework.http.HttpEntity<MultiValueMap<String, Object>> files = new org.springframework.http.HttpEntity<>(form, headers);

		String s = restTemplate.postForObject(url, files, String.class);
		log.info(s);

		return s;

	}



}


